<template>
  <div
    ref="card"
    :class="{
      'task-edit': true,
      isEdit: editMode === 'edit'
    }"
  >
    <section ref="set" class="settings-container">
      <section class="section header">
        <div class="column meter">
          <header>表号</header>
          <section>
            <el-input
              v-model="copied_edit_cell.meter"
              size="mini"
              placeholder="操作表号"
              :disabled="isEditDisabled || editMode === 'edit'"
              style="min-width: 120px"
              @blur="initLightBoxData"
            />
            <el-tooltip
              class="item"
              :effect="theme === 'light' ? 'dark' : 'light'"
              content="保存为预设"
              placement="top"
            >
              <i class="iconfont icon-integral" @click="storeToPreset"></i>
            </el-tooltip>
          </section>
        </div>
        <div class="column charge">
          <header>关联人</header>
          <section>
            <user-list
              :userList="copied_edit_cell.relativeUsers"
              :isAllowEdit="false"
              @add-user="addNewUser"
              @remove-user="removeUser"
            />
          </section>
        </div>
        <div class="column time-range">
          <header>任务周期</header>
          <section>
            <el-date-picker
              v-model="timerange"
              type="daterange"
              size="mini"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['00:00:00', '23:59:59']"
              :disabled="isEditDisabled"
            >
            </el-date-picker>
          </section>
        </div>
        <div class="column preset">
          <header>预设</header>
          <section>
            <el-select
              v-model="current_preset"
              size="mini"
              placeholder="请选择预设模板"
              filterable
              @change="onPresetSelected"
            >
              <el-option-group
                v-for="preset in preset_list"
                :key="preset.label"
                :label="preset.label"
              >
                <el-option
                  v-for="item in preset.options"
                  :key="item.label"
                  :label="item.label"
                  :value="item.label"
                >
                  <div class="custom-preset">
                    <span>{{ item.label.split('.')[0] }}</span>
                    <i
                      v-if="preset.label !== '基础预设'"
                      class="iconfont icon-ashbin"
                      @click.stop="deletePresetItem(item.label)"
                    />
                  </div>
                </el-option>
              </el-option-group>
            </el-select>
          </section>
        </div>
        <!-- <div class="column tool-box">
          <header>工具</header>
          <section>
            <el-tooltip
              class="item"
              :effect="theme === 'dark' ? 'light' : 'dark'"
              content="导出文件"
              placement="top-end"
            >
              <i class="iconfont icon-download"></i>
            </el-tooltip>
            <el-tooltip
              class="item"
              :effect="theme === 'dark' ? 'light' : 'dark'"
              content="新增任务"
              placement="top-end"
            >
              <el-popconfirm
                v-if="editMode === 'add'"
                title="确认新增当前任务吗？"
                trigger="click"
                icon="el-icon-info"
                icon-color="red"
                @confirm="confirmLightBox"
              >
                <i slot="reference" class="iconfont icon-add_task" />
              </el-popconfirm>
            </el-tooltip>
            <el-tooltip
              class="item"
              :effect="theme === 'dark' ? 'light' : 'dark'"
              content="修改任务"
              placement="top-end"
            >
              <el-popconfirm
                v-if="editMode === 'edit'"
                title="确定更新当前操作任务？"
                trigger="click"
                @confirm="updateLightBox"
              >
                <i slot="reference" class="el-icon-refresh" />
              </el-popconfirm>
            </el-tooltip>
            <el-tooltip
              class="item"
              :effect="theme === 'dark' ? 'light' : 'dark'"
              content="关闭窗口"
              placement="top-end"
            >
              <i class="el-icon-close" @click="closeLightBox" />
            </el-tooltip>
          </section>
        </div> -->
        <div class="column remain-days">
          <header>剩余天数</header>
          <section>
            <span>距离计划完成时间还有</span>
            <span class="num">{{ RemainingDays }}</span>
            <span>天</span>
          </section>
        </div>
      </section>
      <section class="section tabs">
        <el-tabs v-model="activeTab">
          <el-tab-pane label="订单信息" name="order">
            <task-tab
              :settings="order_settings"
              @change="onOrderTabChange"
              @onSettingsChange="onTabsValueChange"
            />
          </el-tab-pane>
          <el-tab-pane label="铭牌信息" name="nameplate">
            <task-tab :settings="nameplate_settings" @onSettingsChange="onTabsValueChange" />
          </el-tab-pane>
          <el-tab-pane label="配件信息" name="mountings">
            <task-tab :settings="mountings_settings" @onSettingsChange="onTabsValueChange" />
          </el-tab-pane>
          <el-tab-pane label="备注" name="remarks">
            <task-tab :settings="remarks_settings" @onSettingsChange="onTabsValueChange" />
          </el-tab-pane>
        </el-tabs>
      </section>
      <section class="section operations">
        <div class="module upload">
          <el-upload
            class="upload-demo"
            action=""
            drag
            multiple
            :auto-upload="false"
            list-type="text"
            :show-file-list="false"
            :on-change="uploadLocalFile"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击添加</em></div>
          </el-upload>
          <div class="operation">
            <el-select v-model="currentfilename" size="mini" placeholder="请选择">
              <el-option
                v-for="item in fileOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            <div class="button-container">
              <el-button type="primary" size="mini" @click="previewFileById">预览</el-button>
              <el-button type="primary" size="mini" @click="uploadFileById">上传</el-button>
              <el-button type="primary" size="mini" @click="deleteFileById">删除</el-button>
            </div>
          </div>
        </div>
      </section>
    </section>
    <section v-if="editMode === 'edit'" v-loading="loading" class="procedure-container">
      <!-- 工序数量 -->
      <div ref="message" class="procedure procedure_message">
        <basic-pie
          class="pie"
          :pieData="pieData"
          :selected="filterOptions"
          @on-selected-change="onPieSelectedChange"
        />
      </div>
      <!-- 工序列表 -->
      <ul
        ref="procedule"
        :class="{
          procedure: true,
          isEmpty: filter_procedureList.length === 0
        }"
      >
        <span v-if="filter_procedureList.length === 0">无工序</span>
        <li
          v-for="procedure in filter_procedureList"
          :key="procedure.content.procname"
          :class="{
            isSelected: procedure.content.procname === selectedProcname
          }"
          @click="skipToAccuProcedure(procedure)"
          @contextmenu.prevent="openMenu($event, procedure.content.procname)"
        >
          <span style="min-width: 60px">{{ procedure.content.ip | isValueEmpty }}</span>
          <span>{{ procedure.content.procname }}</span>
          <span :class="['status', getStatus(procedure)]" style="min-width: 60px">
            {{ procedure.content.status }}
          </span>
          <span style="min-width: 60px">{{ procedure.content.operator | isValueEmpty }}</span>
          <span>{{ procedure.content.time | isValueEmpty }}</span>
        </li>
      </ul>
    </section>
    <!-- 特殊组件 -->
    <!-- 文件预览 -->
    <ws-file-preview
      :hidden="isPreviewHidden"
      :file="fileList[currentfilename]"
      @close-preview="onDropClick"
    />
    <!-- 右键菜单 -->
    <div
      v-if="isContextShow"
      class="context-menu"
      :style="contextMenuPosition"
      @click="onContextItemClick($event)"
    >
      <span>关闭工序</span>
      <span>重置工序</span>
      <span>取消操作</span>
    </div>
    <!-- 右侧悬浮工具 -->
    <section ref="tools" class="float-toolbox">
      <!-- 关闭窗口 -->
      <el-tooltip
        class="item"
        :effect="theme === 'dark' ? 'light' : 'dark'"
        content="关闭窗口"
        placement="right"
      >
        <i class="el-icon-close" @click="closeLightBox" />
      </el-tooltip>
      <el-tooltip
        class="item"
        :effect="theme === 'dark' ? 'light' : 'dark'"
        content="导出文件"
        placement="right"
      >
        <i class="iconfont icon-download"></i>
      </el-tooltip>
      <!-- 新增任务 -->
      <el-tooltip
        class="item"
        :effect="theme === 'dark' ? 'light' : 'dark'"
        content="新增任务"
        placement="right"
      >
        <el-popconfirm
          v-if="editMode === 'add'"
          title="确认新增当前任务吗？"
          trigger="click"
          icon="el-icon-info"
          icon-color="red"
          @confirm="confirmLightBox"
        >
          <i slot="reference" class="iconfont icon-add_task" />
        </el-popconfirm>
      </el-tooltip>
      <!-- 更新任务 -->
      <el-tooltip
        class="item"
        :effect="theme === 'dark' ? 'light' : 'dark'"
        content="修改任务"
        placement="right"
      >
        <el-popconfirm
          v-if="editMode === 'edit'"
          title="确定更新当前操作任务？"
          trigger="click"
          @confirm="updateLightBox"
        >
          <i slot="reference" class="el-icon-refresh" />
        </el-popconfirm>
      </el-tooltip>
    </section>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Emit, Prop, Watch, Ref, Provide } from 'vue-property-decorator'
import { TaskCell } from '../settings/interface'
import {
  order_settings,
  nameplate_settings,
  mountings_settings,
  remarks_settings,
  procedure_modules
} from '../settings/basic'
import { SelectOptionsType } from '@/interface/ElementUI'
import { Getter } from 'vuex-class'
import { App } from '@/store/interface/app'
import TaskTab from './TaskTab.vue'
import { Message } from 'element-ui'
import UserList from '@/components/basic/UserList.vue'
import WsFilePreview from '@/components/tool/ws-file-preview.vue'
import BasicPie from '@/components/echarts/basic_pie.vue'
import { Dictionary, WorkersList, TimeLineSetting, SettingType } from '@/interface/Basic'
import {
  GetDataByMeter,
  GetProfileData,
  GetPresetList,
  GetPresetFile,
  StorePresetFile,
  RemovePreset,
  BindSaleOrderToMeter
} from '@/api/dashboard'
import { GetFileListById, UploadFileByID, DeleteFileByID, GetFileData } from '@/api/device'
import { GetProcedureList, ResetProcedure, CloseProcedure } from '@/api/procedure'
import { AxiosResponse } from 'axios'
import { deepClone } from '@/utils/specificFunc'
import { dataURLtoFile, getExtend } from '@/utils/file'
@Component({
  components: {
    TaskTab,
    UserList,
    BasicPie,
    WsFilePreview
  },
  filters: {
    isValueEmpty(value: string) {
      if (value === '') return '无'
      return value
    }
  }
})
class TaskEdit extends Vue {
  @Ref('card') card!: HTMLElement
  @Ref('set') setContainer!: HTMLElement
  @Ref('procedule') procedule!: HTMLElement
  @Ref('message') message!: HTMLElement
  @Ref('tools') tools!: HTMLElement
  @Getter('name') username!: string
  @Getter('theme') theme!: string
  @Getter('sidebar') sidebar!: App['sidebar']
  @Getter('rolesList') rolesList!: Dictionary<Dictionary<string>>
  @Prop({ default: [] }) userNames!: SelectOptionsType<string>
  @Prop({ required: true }) editCell!: TaskCell
  @Prop({ default: 'add', required: true }) editMode!: 'add' | 'edit'
  copied_edit_cell: TaskCell = {
    id: '',
    level: 0,
    progress: 0,
    meter: '',
    start_date: '',
    end_date: '',
    relativeUsers: []
  }
  initial_size: Dictionary<number> = {
    left: 0,
    top: 0,
    width: 0
  }
  // procedure list
  loading: boolean = true
  pieData: {
    name: string
    value: number
  }[] = []
  filterOptions: string[] = []
  procedureList: TimeLineSetting[] = []
  // 右侧列表
  filter_procedureList: TimeLineSetting[] = []
  selectedProcname: string = ''
  isContextShow: boolean = false
  contextMenuPosition: Dictionary<string> = {}
  // relative_users
  isEditUsers: boolean = false
  isEditDisabled: boolean = false
  workers_list: WorkersList[] = []
  // timerange
  timerange: string[] = ['', '']
  // tabs_settings
  activeTab: 'order' | 'nameplate' | 'mountings' = 'order'
  order_settings = order_settings
  nameplate_settings = nameplate_settings
  mountings_settings = mountings_settings
  remarks_settings = remarks_settings
  @Provide('total_settings')
  total_settings: Dictionary<string> = {}
  isPopupConfirm: boolean = false
  // file upload relative
  currentfilename: string = ''
  fileList: Dictionary<File> = {}
  procedure_modules: Dictionary<string> = procedure_modules
  current_drag_item: Dictionary<string> = {}
  isPreviewHidden: boolean = true
  // 分配任务时当前的处理员工
  current_edit_user = ''
  task_assignment: Dictionary<Dictionary<string>> = {}
  // 配置预设
  current_preset: string = ''
  preset_list: {
    label: string
    options: {
      label: string
      value: string
    }[]
  }[] = []
  get RemainingDays() {
    if (this.copied_edit_cell.end_date === '') return 0
    const plan_end_date = new Date(this.copied_edit_cell.end_date).getTime()
    const today = new Date().getTime()
    const delta_time = plan_end_date - today
    if (delta_time <= 0) return 0
    else return Math.floor(delta_time / (24 * 60 * 60 * 1000)) + 1
  }
  get fileOptions() {
    return Object.keys(this.fileList).map(filename => {
      return { label: filename, value: filename }
    })
  }
  get statusList() {
    if (this.procedureList.length === 0) return []
    const map: Dictionary<number> = {}
    this.procedureList.forEach(item => {
      if (!map[item.content.status]) map[item.content.status] = 1
      else map[item.content.status] = map[item.content.status] + 1
    })
    return Object.keys(map).map(status => {
      return {
        label: status,
        value: status,
        num: map[status]
      }
    })
  }
  @Watch('workers_list', { immediate: true })
  w_handler(newVal: WorkersList[]) {
    if (newVal.length === 0) {
      this.$set(this.copied_edit_cell, 'relativeUsers', [
        {
          name: this.username,
          position: '',
          avator: ''
        }
      ])
    } else {
      this.$set(this.copied_edit_cell, 'relativeUsers', newVal)
    }
    this.copied_edit_cell.relativeUsers.forEach(user => {
      this.$set(this.task_assignment, user.name, {})
    })
    this.current_edit_user = this.current_edit_user ? this.current_edit_user : this.username
  }
  @Watch('isEditDisabled')
  ed_handler(newVal: boolean) {
    this.updateTabDisabled(newVal)
  }
  @Watch('copied_edit_cell.meter', { immediate: true })
  e_m_handler(newVal: string, oldVal: string) {
    if (newVal.length < 3 || newVal.toUpperCase() === oldVal.toUpperCase()) return
    this.beforeUpdateTabOptions(newVal.slice(0, 3))
    if (this.editMode === 'edit') this.initLightBoxData()
  }
  @Watch('copied_edit_cell.start_date', { immediate: true })
  start_date_handler(newVal: string) {
    this.$set(this.timerange, 0, newVal)
  }
  @Watch('copied_edit_cell.end_date', { immediate: true })
  end_date_handler(newVal: string) {
    this.$set(this.timerange, 1, newVal)
  }
  @Watch('timerange', { deep: true })
  timerange_handler(newVal: string[]) {
    this.total_settings.AAF2401 = new Date(newVal[0]).toLocaleDateString().replaceAll('/', '-')
    this.total_settings.AAF2301 = new Date(newVal[1]).toLocaleDateString().replaceAll('/', '-')
  }
  @Watch('currentfilename')
  c_handler(newVal: string) {
    if (newVal === '') return
    this.$nextTick(async () => {
      const ext = getExtend(newVal)
      if (!this.fileList[newVal]) {
        if (!this.copied_edit_cell.meter) {
          Message({
            message: '表号未知，检查是否选中记录'
          })
          return
        }
        const response: AxiosResponse<Blob, any> = await GetFileData({
          id: 'main_' + this.copied_edit_cell.meter,
          filename: newVal
        })
        const result = response.data
        this.$set(
          this.fileList,
          newVal,
          new File([result], newVal, {
            type: ['jpg'].includes(ext) ? 'image/jpeg' : ext
          })
        )
      }
    })
  }
  @Watch('statusList')
  sl_handler(newVal: { label: string; value: string }[]) {
    const status = newVal.map(item => item.value)
    const idx = status.findIndex(item => item === '关闭')
    if (this.filterOptions.length) this.filterOptions = deepClone(this.filterOptions)
    else if (idx === -1) this.filterOptions = status
    else {
      status.splice(idx, 1)
      this.filterOptions = status
    }
  }
  @Watch('filterOptions')
  fo_handler(newVal: string) {
    this.filter_procedureList = this.procedureList.filter(item =>
      newVal.includes(item.content.status)
    )
    // 生成 pieData
    this.pieData = this.statusList.map(li => {
      return {
        name: li.label,
        value: li.num
      }
    })
  }
  @Watch('sidebar', { deep: true })
  so_handler() {
    this.animateProcedules()
    this.animateToolbox()
  }
  @Watch('$route')
  route_handler() {
    this.animateToolbox()
  }
  mounted() {
    this.copied_edit_cell = deepClone(this.editCell)
    this.copied_edit_cell.personName = this.username
    this.copied_edit_cell.relativeUsers = [
      {
        name: this.username,
        position: '',
        avator: ''
      }
    ]
    if (this.copied_edit_cell.meter === '') {
      this.updateTabValue({})
      this.updateTabOptions({})
    }
    // 权限校验，判断当前用户是否有可编辑的权限
    this.initEditable()
    this.initPrestList()
    this.animateToolbox()
    window.addEventListener('resize', () => {
      this.animateProcedules()
      this.animateToolbox()
    })
  }
  @Emit()
  closeLightBox() {
    return false
  }
  @Emit()
  confirmLightBox() {
    return [this.total_settings]
    // 将数据发送给后台存储
    /**
     * 可以将数据存储分成多个模块
     *    修改任务关联人与任务分配
     *    修改任务配置信息
     */
  }
  @Emit()
  updateLightBox() {
    return this.total_settings
  }
  // lightbox relative
  // permission
  initEditable() {
    const { AAF } = this.rolesList
    const arr = Object.values(AAF)
    const num = arr.filter(item => item === '0').length
    this.isEditDisabled = num === arr.length
  }
  initLightBoxData() {
    const { meter } = this.copied_edit_cell
    // 如果填入的表号与当前的预设不匹配，取消操作
    if (!this.isPresetMatchMeter(meter, this.current_preset)) {
      this.$set(this.copied_edit_cell, 'meter', '')
      return
    }
    // 将填入的表号全部转化为大写
    if (/[a-z]{1,}/.test(meter)) {
      this.$set(this.copied_edit_cell, 'meter', meter.toUpperCase())
    }
    this.total_settings.AAF001 = meter
    if (this.editMode === 'add') return
    GetDataByMeter(meter).then((res: AxiosResponse<{ ReturnData: Dictionary<string> }>) => {
      const { ReturnData } = res.data
      const { AAF2301, AAF2401 } = ReturnData
      this.updateTabValue(ReturnData)
      this.$set(this.copied_edit_cell, 'start_date', AAF2401)
      this.$set(this.copied_edit_cell, 'end_date', AAF2301)
    })
    this.updateFileList(meter)
    this.initProcedureList()
  }
  initProcedureList() {
    if (this.editMode === 'add') return
    const { meter } = this.copied_edit_cell
    GetProcedureList(meter).then((res: AxiosResponse<{ ReturnData: TimeLineSetting[] }>) => {
      const { ReturnData } = res.data
      const disabled_procedure_num = ReturnData.filter(item => item.disabled).length
      if (disabled_procedure_num === ReturnData.length) {
        Message({
          message: '您没有任何工序的操作权限，请联系管理员授予',
          type: 'error'
        })
      }
      this.procedureList = ReturnData
      this.loading = false
      this.animateProcedules()
      this.animateToolbox()
    })
  }
  animateProcedules() {
    if (this.editMode === 'add') return
    this.$nextTick(() => {
      this.$nextTick(() => {
        if (!this.setContainer || !this.message) return
        const { height: set_height } = this.setContainer.getBoundingClientRect()
        const { height: message_height } = this.message.getBoundingClientRect()
        this.procedule.animate(
          [{ height: 0 }, { height: set_height - message_height - 10 + 'px' }],
          {
            duration: 500,
            easing: 'ease',
            fill: 'both'
          }
        )
      })
    })
  }
  animateToolbox() {
    if (!this.card) return
    let { left, width, top } = this.card.getBoundingClientRect()
    const { left: s_left, width: s_width, top: s_top } = this.initial_size
    if (left !== 0 && width !== 0 && top !== 0) {
      this.initial_size = { left, top, width }
    }
    left = left === 0 ? s_left : left
    width = width === 0 ? s_width : width
    top = top === 0 ? s_top : top
    this.tools.animate(
      [
        {
          height: 0,
          top: top + 200 + 'px',
          left: left + width + 10 + 'px',
          opacity: 0.2,
          scale: 0
        },
        {
          height: '120px',
          top: top - 1 + 'px',
          left: left + width + 10 + 'px',
          opacity: 1,
          scale: 1
        }
      ],
      {
        duration: 800,
        easing: 'cubic-bezier(0.43, 0.23, 0.25, 1.44)',
        fill: 'both'
      }
    )
  }
  // preset
  // 判断预设与表号是否匹配
  generateMeterByPreset(presetName: string) {
    let prefix: string[] = []
    if (/WAB|[1-9]{1,}/.test(presetName.slice(0, 3))) prefix = [presetName.slice(0, 3)]
    else if (presetName.indexOf('CL-2M') !== -1) prefix = ['WA4', 'WA6', 'WA9', 'WAB']
    else if (presetName.indexOf('CL-1') !== -1) prefix = ['WA1', 'WA8']
    return prefix
  }
  isPresetMatchMeter(meter: string, presetName: string) {
    if (meter === '' || presetName === '') return true
    const prefix = this.generateMeterByPreset(presetName)
    const meter_type = meter.toUpperCase().slice(0, 3)
    if (!prefix.includes(meter_type)) {
      Message({
        type: 'warning',
        message: `选中预设并非 ${meter_type} 类型`
      })
      return false
    }
    return true
  }
  initPrestList() {
    interface PresetType {
      label: string
      options: {
        Name: string
        FullName: string
      }[]
    }
    GetPresetList().then((res: AxiosResponse<{ ReturnData: PresetType[] }>) => {
      const { ReturnData } = res.data
      this.preset_list = ReturnData.map(item => {
        const newOptions = item.options.map(option => {
          return {
            label: option.Name,
            value: option.Name
          }
        })
        return {
          label: item.label,
          options: newOptions
        }
      })
    })
  }
  storeToPreset() {
    if (this.copied_edit_cell.meter.length === 0) {
      Message({
        type: 'warning',
        message: '请提供表号信息'
      })
      return
    }
    StorePresetFile(this.total_settings).then(() => {
      Message({
        type: 'success',
        message: '预设保存成功'
      })
      this.initPrestList()
    })
  }
  onPresetSelected(preset: string) {
    if (preset === '') return
    if (!this.isPresetMatchMeter(this.copied_edit_cell.meter, preset)) {
      this.current_preset = ''
      return
    }
    let select_group: string = ''
    this.preset_list.forEach(label => {
      const select_item = label.options.find(item => item.label === preset)
      if (select_item && select_group === '') {
        select_group = label.label
      }
    })
    interface PresetFileType {
      key: string
      value: string
    }
    GetPresetFile({ label: select_group, Name: preset }).then(
      (res: AxiosResponse<{ ReturnData: PresetFileType[] }>) => {
        const { ReturnData } = res.data
        const obj: Dictionary<string> = {}
        ReturnData.forEach(item => {
          obj[item.key] = item.value
        })
        this.updateTabValue(obj)
        this.timerange = [obj.AAF2401, obj.AAF2301]
      }
    )
    this.beforeUpdateTabOptions(this.generateMeterByPreset(preset)[0])
  }
  deletePresetItem(presetName: string) {
    RemovePreset({ filename: presetName }).then((res: AxiosResponse<{ Message: string }>) => {
      Message({
        type: 'success',
        message: res.data.Message
      })
      if (this.current_preset === presetName) this.current_preset = ''
      this.initPrestList()
    })
  }
  // users
  startEditUsers() {
    if (this.isEditUsers) return
    this.isEditUsers = true
  }
  addNewUser(users: WorkersList[]) {
    this.workers_list = users
  }
  removeUser(users: WorkersList[]) {
    this.workers_list = users
  }
  // toolbox
  skipToProcedureManage() {
    const { meter: meterid } = this.copied_edit_cell
    // GetProcedureList(meterid).then((res: AxiosResponse<{ ReturnData: TimeLineSetting[] }>) => {
    //   const { ReturnData } = res.data
    //   const disabled_procedure_num = ReturnData.filter(item => item.disabled).length
    //   if (disabled_procedure_num === ReturnData.length) {
    //     Message({
    //       message: '您没有该工序的操作权限，请联系管理员授予',
    //       type: 'error'
    //     })
    //     return
    //   }
    // })
    if (meterid === '') {
      Message({
        type: 'warning',
        message: '表号为空'
      })
      return
    } else if (this.editMode === 'add') {
      Message({
        type: 'warning',
        message: '新增任务时不允许跳转'
      })
      return
    }
    this.$router.push({
      name: 'dashboard',
      params: { meterid }
    })
  }
  getStatus(procedure: TimeLineSetting) {
    const str = []
    str.push(`is-${procedure.type}`)
    if (procedure.disabled) str.push('is-disabled')
    if (procedure.content.status === '关闭') str.push('is-closed')
    return str.join(' ')
  }
  skipToAccuProcedure(procedure: TimeLineSetting) {
    const { disabled, content } = procedure
    const { meter: meterid } = this.copied_edit_cell
    if (disabled || content.status === '关闭') {
      Message({
        type: 'error',
        message: '该工序暂不支持直接跳转'
      })
      return
    }
    if (meterid === '') {
      Message({
        type: 'warning',
        message: '表号为空'
      })
      return
    } else if (this.editMode === 'add') {
      Message({
        type: 'warning',
        message: '新增任务时不允许跳转'
      })
      return
    }
    this.$broadEmit('onEnterProcedure', this.total_settings)
    this.$router.push({
      name: 'dashboard',
      params: { meterid },
      query: {
        procname: content.procname
      }
    })
  }
  // tabs
  beforeUpdateTabOptions(prefix: string) {
    interface ReturnDataType {
      key: string
      value: string
    }
    GetProfileData(prefix)
      .then((res: AxiosResponse<{ ReturnData: ReturnDataType[] }>) => {
        const { ReturnData } = res.data
        const obj: Dictionary<SelectOptionsType<string>> = {}
        ReturnData.forEach(item => {
          const splitValue = item.value.split(',')
          const formatValue = splitValue.slice(0, splitValue.length - 1).map(item => {
            return { label: item, value: item }
          })
          obj[item.key] = formatValue
        })
        this.updateTabOptions(obj)
      })
      .catch(() => this.updateTabOptions({}))
  }
  updateTabOptions(origin: Dictionary<SelectOptionsType<string>>) {
    function updateOptions(arr: SettingType[], origin: Dictionary<SelectOptionsType<string>>) {
      return arr.map(item => {
        if (item.options) item.options = []
        if (origin[item.key]) {
          item.options = origin[item.key].length ? origin[item.key] : []
        }
        return item
      })
    }
    this.order_settings = updateOptions(this.order_settings, origin)
    this.nameplate_settings = updateOptions(this.nameplate_settings, origin)
    this.mountings_settings = updateOptions(this.mountings_settings, origin)
    this.remarks_settings = updateOptions(this.remarks_settings, origin)
  }
  updateTabDisabled(isEditDisabled: boolean) {
    function updateDisabled(arr: SettingType[], isDisabled: boolean) {
      return arr.map(item => {
        if (item.key !== 'static') {
          item.disabled = isDisabled
        }
        return item
      })
    }
    this.order_settings = updateDisabled(this.order_settings, isEditDisabled)
    this.nameplate_settings = updateDisabled(this.nameplate_settings, isEditDisabled)
    this.mountings_settings = updateDisabled(this.mountings_settings, isEditDisabled)
    this.remarks_settings = updateDisabled(this.remarks_settings, isEditDisabled)
  }
  updateTabValue(response_data: Dictionary<string>) {
    function updateValue(arr: SettingType[], response_data: Dictionary<string>) {
      return arr.map(li => {
        if (li.key === 'static') return li
        li.value = response_data[li.key] ? response_data[li.key] : ''
        return li
      })
    }
    console.log('z', response_data)
    if (response_data.AAF301) {
      const { meter } = this.copied_edit_cell
      BindSaleOrderToMeter(meter, response_data.AAF301).then(res => {
        console.log(res)
        this.updateFileList(meter)
      })
    }
    this.order_settings = updateValue(this.order_settings, response_data)
    this.nameplate_settings = updateValue(this.nameplate_settings, response_data)
    this.mountings_settings = updateValue(this.mountings_settings, response_data)
    this.remarks_settings = updateValue(this.remarks_settings, response_data)
  }
  onTabsValueChange(e: Dictionary<string>) {
    const settings = { ...this.total_settings, ...e }
    if (settings.static) {
      const { static: static_proper, ...rest } = settings
      this.total_settings = rest
    } else {
      this.total_settings = settings
    }
  }
  onOrderTabChange(e: { item: SettingType; dict: Dictionary<string> }) {
    const { meter } = this.copied_edit_cell
    const { item, dict } = e
    if (item.key === 'AAF301') {
      const saleOrderNumber = dict[item.key]
      BindSaleOrderToMeter(meter, saleOrderNumber).then(() => {
        this.updateFileList(meter)
      })
    }
  }
  // file upload
  updateFileList(meter: string) {
    if (this.editMode === 'add') return
    GetFileListById({ id: 'main_' + meter }).then(
      (res: AxiosResponse<{ ReturnData: Dictionary<string>[] }>) => {
        res.data.ReturnData.forEach(item => {
          this.$set(this.fileList, item.Name, null)
        })
        this.currentfilename = res.data.ReturnData[0] ? res.data.ReturnData[0].Name : ''
      }
    )
  }
  async uploadLocalFile(file: any) {
    const { name, raw } = file
    // const arrayBuffer = await readBuffer(raw)
    this.$set(this.fileList, name, raw)
    this.currentfilename = name
  }
  previewFileById() {
    this.isPreviewHidden = false
  }
  uploadFileById() {
    // if (!this.beforeOperation()) return
    const { meter } = this.copied_edit_cell
    if (!meter) {
      Message({
        message: '表号未知，请确认是否选择记录',
        type: 'warning'
      })
      return
    }
    let file = this.fileList[this.currentfilename]
    if (file instanceof File) {
      // 文件是 file 类型
    } else {
      file = dataURLtoFile(file, this.currentfilename)
    }
    const fd = new FormData()
    fd.append('id', 'main_' + meter)
    fd.append('file', this.currentfilename)
    fd.append('file', file)
    UploadFileByID(fd).then(() => {
      this.updateFileList(meter)
      Message({
        message: '文件上传成功',
        type: 'warning'
      })
    })
  }
  deleteFileById() {
    // if (!this.beforeOperation()) return
    // if (!this.edit_cell.id) return
    const { meter } = this.copied_edit_cell
    DeleteFileByID({
      id: 'main_' + meter,
      fileName: this.currentfilename
    })
      .then(() => {
        Message({
          message: '文件删除成功',
          type: 'success'
        })
        this.$delete(this.fileList, this.currentfilename)
        this.currentfilename =
          Object.keys(this.fileList).length === 0 ? '' : Object.keys(this.fileList)[0]
      })
      .catch(() => {
        Message({
          message: '文件删除失败',
          type: 'error'
        })
      })
  }
  onDropClick(hidden: boolean) {
    this.isPreviewHidden = hidden
  }
  // task deliver
  handleDragStart(procedure: string) {
    const obj: Dictionary<string> = {}
    obj[procedure] =
      this.procedure_modules[procedure] === undefined
        ? this.task_assignment[this.current_edit_user][procedure]
        : this.procedure_modules[procedure]
    this.current_drag_item = obj
  }
  handleProcedureOver(e: any) {
    e.preventDefault()
  }
  onProcedureDrop(type: 'add' | 'remove') {
    const user = this.current_edit_user
    const key = Object.keys(this.current_drag_item)[0]
    const label = this.current_drag_item[key]
    // 将任务分配给员工
    if (type === 'add') {
      this.$delete(this.procedure_modules, key)
      this.$set(this.task_assignment[user], key, label)
    } else {
      // 将任务从员工处移除
      this.$delete(this.task_assignment[user], key)
      this.$set(this.procedure_modules, key, label)
    }
  }
  // 右侧
  onPieSelectedChange(selected: string[]) {
    this.filterOptions = selected
    this.animateProcedules()
  }
  openMenu(e: MouseEvent, procname: string) {
    const { pageX, pageY } = e
    const { left, top } = this.card.getBoundingClientRect()
    const [deltaX, deltaY] = [pageX - left, pageY - top]
    this.contextMenuPosition = {
      left: deltaX + 'px',
      top: deltaY + 'px'
    }
    this.selectedProcname = procname
    this.isContextShow = true
  }
  onContextItemClick(e: MouseEvent) {
    const item = e.target as HTMLElement
    if (!item.innerText) return
    const text = item.innerText
    if (text === '关闭工序') {
      this.closeProcedure()
    } else if (text === '重置工序') {
      this.resetProcedure()
    }
    this.isContextShow = false
    this.selectedProcname = ''
  }
  resetProcedure() {
    ResetProcedure({
      Procname: this.selectedProcname,
      Number: this.copied_edit_cell.meter,
      Operator: this.username
    }).then((res: AxiosResponse<{ Message: string }>) => {
      Message({
        type: 'success',
        message: res.data.Message
      })
      this.initProcedureList()
    })
  }
  closeProcedure() {
    CloseProcedure({
      Procname: this.selectedProcname,
      Number: this.copied_edit_cell.meter,
      Operator: this.username
    }).then((res: AxiosResponse<{ Message: string }>) => {
      Message({
        type: 'success',
        message: res.data.Message
      })
      this.initProcedureList()
    })
  }
}
export default TaskEdit
</script>

<style lang="less" scoped>
@import '~@/styles/theme.less';
@import '~@/styles/layout.less';
@import '~@/styles/variable.less';
@import '~@/styles/mixin.less';
.task-edit {
  position: relative;
  box-sizing: border-box;
  padding: 20px;
  width: 60%;
  min-width: 800px;
  max-height: calc(100vh - 60px);
  transition: all 0.5s ease;
  overflow-y: auto;
  transition: width 0.2s ease;
  #flex(row, flex-start, space-between);
  #color(background-color, --module-bg-color);
  h4 {
    position: relative;
    box-sizing: border-box;
    margin: 0;
    margin-right: 5px;
    font-size: 14px;
    font-weight: 400;
    #color(color, --primary-text-color);
  }
  .settings-container {
    flex: 1.5;
    height: 100%;
    #flex(column, flex-start, space-between);
    .section {
      box-sizing: border-box;
      width: 100%;
      flex: 1;
      padding: 10px;
      margin-bottom: 10px;
      border-radius: 5px;
      #shadow-color(0, 2px, 10px, 0, --lighter-shadow-color);
    }
    .section:last-child {
      margin-bottom: 0;
    }
    .header {
      padding-bottom: 8px;
      width: 100%;
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: flex-start;
      border-bottom: solid 1px rgba(0, 0, 0, 0.2);
      .column {
        box-sizing: border-box;
        margin: 10px 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: flex-start;
        margin-right: 20px;
        padding-right: 20px;
        border-right: solid 1px;
        #color(border-right-color, --primary-border-color);
        header {
          margin-bottom: 5px;
          width: 100%;
          text-align: left;
          font-size: 12px;
          font-weight: 400;
          #color(color, --lighter-text-color);
        }
        section {
          display: flex;
          flex-wrap: wrap;
          align-items: center;
          box-sizing: border-box;
          padding: 6px 0;
        }
      }
      .column:last-child {
        border-right: solid 0;
      }
      .meter {
        /deep/.el-input {
          width: 100px;
          #shadow-color(1px, 1px, 4px, 0, --primary-shadow-color);
        }
        i {
          box-sizing: border-box;
          padding: 5px;
          margin-left: 10px;
          border-radius: 5px;
          border: solid 1px;
          transition: all 0.2s ease;
          cursor: pointer;
          #color(border-color, --primary-border-color);
          #color(color, --primary-text-color);
          #color(background-color, --primary-bg-color);
          #shadow-color(1px, 1px, 4px, 0, --primary-shadow-color);
        }
        i:hover {
          color: #ffffff;
          border-color: #dark[ @--primary-blue-color];
          #color(background-color, --primary-blue-color);
        }
      }
      .time-range,
      .preset {
        /deep/.el-date-editor,
        /deep/.select {
          width: 200px;
          #shadow-color(1px, 1px, 4px, 0, --primary-shadow-color);
        }
      }
      .remain-days {
        section {
          width: 100%;
          display: flex;
          align-items: baseline;
          span {
            font-size: 12px;
            #color(color, --primary-text-color);
          }
          .num {
            display: block;
            margin: 0 8px;
            font-size: 16px;
            font-weight: 800;
            #color(color, --primary-red-color);
          }
        }
      }
      .tool-box {
        section {
          padding: 2px 0;
          /deep/.el-popover__reference-wrapper {
            display: flex;
            align-items: center;
            justify-content: center;
          }
        }
        i {
          box-sizing: border-box;
          padding: 5px;
          border-radius: 2px;
          font-size: 18px;
          color: #ffffff;
          margin-right: 5px;
          cursor: pointer;
          transition: all 0.5s ease;
          #color(background-color, --primary-blue-color);
        }
        i:hover {
          #color(background-color, --heavier-blue-color);
        }
      }
    }
    .tabs {
      width: 100%;
      padding-bottom: 10px;
      display: flex;
      align-items: flex-start;
      justify-content: flex-start;
      border-bottom: solid 1px rgba(0, 0, 0, 0.2);
      /deep/.el-tabs {
        width: 100%;
        .el-tabs__content {
          height: 280px;
          overflow: auto;
        }
      }
    }
    .operations {
      padding: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
      box-shadow: unset;
      .module {
        box-sizing: border-box;
        padding: 10px;
        flex: 1;
        width: 100%;
        border-radius: 5px;
        #shadow-color(0, 2px, 10px, 0, --lighter-shadow-color);
      }
      .upload {
        display: flex;
        flex-direction: column;
        align-items: center;
        .upload-demo {
          width: 100%;
          margin-bottom: 10px;
          /deep/.el-upload {
            width: 100%;
            .el-upload-dragger {
              display: flex;
              flex-direction: column;
              align-items: center;
              justify-content: center;
              width: 100%;
              height: 120px;
              i {
                margin: 0;
              }
            }
          }
        }
        .operation {
          flex: 1;
          width: 100%;
          display: flex;
          flex-wrap: wrap;
          align-items: center;
          justify-content: space-between;
          /deep/.el-select {
            flex: 1;
            margin-right: 10px;
          }
          .button-container {
            flex: 1;
            display: flex;
            flex-wrap: nowrap;
            /deep/.el-button {
              flex: 1;
            }
          }
        }
      }
      .deliver {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        .container {
          flex: 1;
          height: 100%;
          margin: 0 5px;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: flex-start;
          header {
            box-sizing: border-box;
            width: 100%;
            height: 28px;
            display: flex;
            align-items: center;
            justify-content: flex-start;
            text-align: left;
            padding-bottom: 5px;
            margin-bottom: 5px;
            border-bottom: solid 1px;
            font-size: 14px;
            #color(color, --primary-text-color);
            #color(border-color, --primary-border-color);
            span {
              margin-right: 15px;
            }
            .el-select {
              flex: 1;
            }
          }
          section {
            flex: 1;
            width: 100%;
            margin: 0 10px;
            display: flex;
            flex-wrap: wrap;
            align-items: flex-start;
            align-content: flex-start;
            justify-content: flex-start;
            overflow: auto;
            box-shadow: inset 0 0 4px #light[ @--primary-shadow-color];
            [data-theme='dark'] & {
              box-shadow: inset 0 0 4px 1px #dark[ @--primary-shadow-color];
            }
            span {
              box-sizing: border-box;
              padding: 4px 6px;
              margin: 8px 0;
              margin-left: 8px;
              font-size: 12px;
              border: solid 1px;
              transition: all 0.2s ease;
              cursor: pointer;
              #color(color, --primary-text-color);
              #color(border-color, --primary-border-color);
              #shadow-color(2px, 2px, 4px, 0, --primary-shadow-color);
            }
            span:hover {
              color: #ffffff;
              #color(background-color, --lighter-blue-color);
            }
          }
          ::-webkit-scrollbar {
            width: 0;
          }
        }
      }
    }
    .footer {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .preset-container {
        display: flex;
        align-items: center;
        span {
          font-size: 12px;
          margin-right: 5px;
          #color(color, --primary-text-color);
        }
      }
      .button-container {
        .el-button {
          margin: 0;
          margin-left: 10px;
          transition: background-color 0.2s ease;
        }
        .el-button:hover {
          #color(background-color, --heavier-blue-color);
        }
        .delete_button {
          .el-button:hover {
            #color(background-color, --heavier-red-color);
          }
        }
      }
    }
  }
  .procedure-container {
    flex: 0.5;
    min-width: 300px;
    border-radius: 5px;
    height: 100%;
    margin-left: 20px;
    #flex(column, center, flex-start);
    .procedure {
      box-sizing: border-box;
      padding: 10px 15px;
      width: 100%;
      #shadow-color(0, 2px, 10px, 0, --lighter-shadow-color);
      span {
        font-size: 14px;
        #color(color, --primary-text-color);
      }
    }
    .procedure_message {
      flex-wrap: wrap;
      margin-bottom: 10px;
      height: 150px;
      #flex(row, center, flex-start);
      span {
        display: block;
        width: 50%;
        min-width: 100px;
        line-height: 30px;
        text-align: left;
        white-space: nowrap;
      }
    }
    .procedure_filter {
      margin-bottom: 10px;
      #flex(row, center, space-between);
      span {
        margin-right: 10px;
      }
    }
    ul {
      padding: 10px;
      overflow: auto;
      #flex(column, flex-start, flex-start);
      li {
        position: relative;
        box-sizing: border-box;
        padding: 8px;
        border-radius: 2px;
        border-bottom: solid 1px;
        transition: all 0.2s ease;
        cursor: pointer;
        #flex(row, center, space-between);
        #color(border-bottom-color, --lighter-border-color);
        span {
          min-width: 120px;
          font-size: 14px;
          text-align: left;
          white-space: nowrap;
          #color(color, --primary-text-color);
        }
        .status {
          box-sizing: border-box;
          padding: 2px 0;
          margin-right: 20px;
          font-size: 12px;
          text-align: center;
          border-radius: 2px;
          color: #ffffff;
        }
        .is-completed {
          #color(background-color, --primary-green-color);
        }
        .is-uncompleted {
          #color(background-color, --primary-red-color);
        }
        .is-disabled,
        .is-closed {
          #color(background-color, --primary-scroll-color);
        }
      }
      li:hover {
        #color(background-color, --primary-hover-text-color);
      }
      .isSelected {
        #color(background-color, --primary-blue-color);
        span {
          color: #ffffff;
        }
      }
    }
    .isEmpty {
      #flex(column, center, center);
    }
  }
  .context-menu {
    position: absolute;
    top: 0;
    left: 0;
    border-radius: 5px;
    border: solid 1px;
    overflow: hidden;
    #flex(column, center, flex-start);
    #color(border-color, --primary-border-color);
    #color(background-color, --module-bg-color);
    #shadow-color(0, 0, 4px, 0, --primary-shadow-color);
    span {
      box-sizing: border-box;
      padding: 8px 10px;
      font-size: 12px;
      border-bottom: solid 1px;
      cursor: pointer;
      transition: all 0.2s ease;
      #color(color, --primary-text-color);
      #color(border-color, --primary-border-color);
    }
    span:last-child {
      border-bottom: unset;
    }
    span:hover {
      color: #ffffff;
      #color(background-color, --primary-blue-color);
    }
  }
  .float-toolbox {
    position: fixed;
    overflow: hidden;
    #flex(column, flex-start, flex-start);
    /deep/.el-popover__reference-wrapper {
      display: flex;
      align-items: center;
      justify-content: center;
    }
    i {
      box-sizing: border-box;
      padding: 5px;
      margin-bottom: 10px;
      border-radius: 2px;
      border: solid 1px;
      font-size: 18px;
      color: #ffffff;
      cursor: pointer;
      transition: all 0.5s ease;
      #color(color, --primary-text-color);
      #color(background-color, --module-bg-color);
      #color(border-color, --primary-border-color);
    }
    i:hover {
      border-radius: 5px;
      color: #ffffff;
      #color(border-color, --primary-blue-color);
      #color(background-color, --primary-blue-color);
    }
  }
}
.isEdit {
  width: 70%;
}
.custom-preset {
  #flex(row, center, space-between);
  i {
    color: #808080;
    font-weight: 400;
    transition: color, 0.2s ease;
  }
  i:hover {
    #color(color, --primary-blue-color) !important;
  }
}
/deep/::-webkit-scrollbar {
  width: 0 !important;
  height: 8px !important;
}
</style>
